package com.xuecheng.content.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuecheng.base.exception.XueChengPlusException;
import com.xuecheng.content.mapper.TeachplanMapper;
import com.xuecheng.content.model.dto.SaveTeachplanDto;
import com.xuecheng.content.model.dto.TeachplanDto;
import com.xuecheng.content.model.po.Teachplan;
import com.xuecheng.content.service.TeachplanService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.constraints.Min;
import java.util.List;

/**
 * <p>
 * 课程计划 服务实现类
 * </p>
 *
 * @author itcast
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class TeachplanServiceImpl extends ServiceImpl<TeachplanMapper, Teachplan> implements TeachplanService {
    private final TeachplanMapper teachplanMapper;

    @Override
    public List<TeachplanDto> findTeachplanTree(long courseId) {
        return teachplanMapper.selectTreeNodes(courseId);
    }

    @Override
    @Transactional
    //同一个接口接收新增和修改两个业务请求，以是否传递课程计划id 来判断是新增还是修改。
    //如果传递了课程计划id说明当前是要修改该课程计划，否则是新增一个课程计划。
    public void saveTeachplan(SaveTeachplanDto teachplanDto) {
        //课程计划id
        Long id = teachplanDto.getId();

        //修改课程计划
        if (id!=null){
            Teachplan teachplan = BeanUtil.copyProperties(teachplanDto, Teachplan.class);
            updateById(teachplan);
        }else {
            //取出同父级别的课程计划数量
            //取出同父同级别的课程计划数量
//            int count = getTeachplanCount(teachplanDto.getCourseId(), teachplanDto.getParentid());
            Teachplan teachplanNew = new Teachplan();
            List<Teachplan> list = lambdaQuery()
                    .eq(Teachplan::getCourseId, teachplanDto.getCourseId())
                    .eq(Teachplan::getParentid, teachplanDto.getParentid())
                    .list();

            int maxOrder = getMaxOrder(list);
            //设置排序号
            teachplanNew.setOrderby(maxOrder+1);


            BeanUtil.copyProperties(teachplanDto,teachplanNew);
            save(teachplanNew);
        }
    }


    /**
     * @description 获取最新的排序号
     * @param courseId  课程id
     * @param parentId  父课程计划id
     * @return int 最新排序号
     * @author Mr.M
     * @date 2022/9/9 13:43
     */
    private int getTeachplanCount(Long courseId, Long parentId) {
        Long count = lambdaQuery()
                .eq(Teachplan::getCourseId, courseId)
                .eq(Teachplan::getParentid, parentId)
                .count();

        return Math.toIntExact(count);
    }


    @Override
    public void deleteTeachplan(Long id) {
        List<Teachplan> list = lambdaQuery()
                .eq(Teachplan::getParentid, id)
                .list();

        if (!list.isEmpty()){
           XueChengPlusException.cast("120409","课程计划信息还有子级信息，无法操作");
        }else {
            removeById(id);
        }
    }

    @Override
    public void moveDown(Long id,String way) {
        Teachplan teachplanObj = getById(id);
        Integer orderby = teachplanObj.getOrderby();

        Long courseId = teachplanObj.getCourseId();

        Long parentid = teachplanObj.getParentid();
        List<Teachplan> list = lambdaQuery()
                .eq(Teachplan::getParentid, parentid)
                .eq(Teachplan::getCourseId,courseId)
                .list();

        if (way.equals("down")){
            int maxOrder = getMaxOrder(list);

            if (orderby.equals(maxOrder)){
                XueChengPlusException.cast("已是最后一个章节，无法向下移动");
            }
            int downOrder= orderby +1;

            extracted(orderby, parentid, teachplanObj,downOrder,courseId);


        }else if (way.equals("up")){
            int minOrder = getMinOrder(list);

            if (orderby.equals(minOrder)){
                XueChengPlusException.cast("已是第一个章节，无法向上移动");
            }
            int upOrder=orderby-1;

           extracted(orderby,parentid,teachplanObj,minOrder,courseId);

        }




    }

    private void extracted(Integer orderby, Long parentid, Teachplan teachplanObj  ,int moveOrder,Long courseId) {
        Teachplan downTeachPlan = lambdaQuery()
                .eq(Teachplan::getParentid, parentid)
                .eq(Teachplan::getOrderby, orderby)
                .eq(Teachplan::getCourseId,courseId)
                .one();

        downTeachPlan.setOrderby(orderby);
        updateById(downTeachPlan);

        teachplanObj.setOrderby(moveOrder);
        updateById(teachplanObj);
    }

    private static int getMaxOrder(List<Teachplan> list) {
        int  maxOrder=0;
        for (Teachplan teachplan : list) {
            maxOrder=teachplan.getOrderby()>maxOrder ? teachplan.getOrderby():maxOrder;
        }
        return maxOrder;
    }

    private static int getMinOrder(List<Teachplan> list) {
        int  minOrder=1;
        for (Teachplan teachplan : list) {
            minOrder=teachplan.getOrderby()<minOrder ? teachplan.getOrderby():minOrder;
        }
        return minOrder;
    }


}
